package services

import (
	"errors"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"strings"
	"time"
	"weiboxs.com/new_h_glasses/models"
	"weiboxs.com/new_h_glasses/utils"
)

type CollectfeesService struct {
}

func (s *CollectfeesService) create_number(depid int64) string {
	stat := utils.GetDateParse(time.Now().Format("2006-01-02"))
	end := stat + 86400
	return fmt.Sprintf("MZ%s%04d", time.Now().Format("200601021504"), models.QuerySaCollectfeesDoctororderCount(depid, stat, end, )+1)
}

//执行结帐
func (s *CollectfeesService) SaCollectfeesDoctororderSave(value *models.SaCollectfeesDoctororder) error {
	to, _ := orm.NewOrm().Begin()
	if value.Archives.Id == 0 {
		return errors.New("档案信息不存在")
	}
	//结帐记录
	chk_sum_payable := value.CardMoney + value.CashMoney + value.WechatMoney + value.AlipayMoney
	if chk_sum_payable != value.SumPayable { //判断应付是否相等
		return errors.New("应付金额不符")
	}
	value.CreatedAt = time.Now().Unix()
	value.Number = s.create_number(value.DepartmentId)
	value.ParentId = 0
	if _, err := to.Insert(value); err != nil {
		to.Rollback()
		return err
	}
	//医嘱信息
	if len(value.DetailIds) <= 0 {
		to.Rollback()
		return errors.New("可结算信息为空")
	}
	//获取医嘱
	doctorOrder := models.DoDoctorOrderList(&models.DoDoctorOrderQueryParam{Id: strings.Split(value.DetailIds, ","), Department: value.DepartmentId, Archives: value.Archives.Id})
	if len(doctorOrder) == 0 {
		to.Rollback()
		return errors.New("没有可结算的信息")
	}
	for k, _ := range doctorOrder { //循环执行
		v := doctorOrder[k]
		if v.Status != 1 || v.PayStatus != 0 {
			to.Rollback()
			return errors.New("待结算信息状态不正常")
		}
		//生成中间表数据
		middle := new(models.SaCollectfeesDoctororderMiddle)
		middle.Collectfees = value
		middle.Doctororder = v
		middle.CreatedAt = value.CreatedAt
		middle.CreatedBy = value.CreatedBy
		middle.TotalMoney = v.TotalPrice
		middle.SumPayable = v.TotalPrice
		if _, err := to.Insert(middle); err != nil {
			to.Rollback()
			return err
		}
		v.PayStatus = 1;
		v.CollectfeesMiddleId = middle.Id
		if _, err := to.Update(v); err != nil {
			to.Rollback()
			return err
		}
		//药品库存
		if v.ProjectType == "drug" {
			inv := models.ErpInventoryFind(v.Inventory.Id)
			if err := cutInventory(to, value.Number, inv, v.DosageZl); err != nil {
				to.Rollback()
				return err
			}
		}
	}
	to.Commit()
	return nil
}

//判断是否存在
func inIntSliceMapKeyFunc(haystack []string) func(string) bool {
	set := make(map[string]struct{})
	for _, e := range haystack {
		set[e] = struct{}{}
	}
	return func(needle string) bool {
		_, ok := set[needle]
		return ok
	}
}

//执行退费
func (s *CollectfeesService) SaCollectfeesDoctororderOut(value *models.SaCollectfeesDoctororder) error {
	to, _ := orm.NewOrm().Begin()
	if value.Archives.Id == 0 {
		return errors.New("档案信息不存在")
	}
	if value.Id == 0 {
		return errors.New("退费单据不存在")
	}
	//结帐记录
	chk_sum_payable := value.CardMoney + value.CashMoney + value.WechatMoney + value.AlipayMoney
	if chk_sum_payable != value.SumPayable { //判断应付是否相等
		to.Rollback()
		return errors.New("应付金额不符")
	}

	logs_id := value.Id
	logs, err := models.GetSaCollectfeesDoctororderById(logs_id)
	if err != nil {
		return err
	}
	if logs.Status != 0 {
		to.Rollback()
		return errors.New("单据已退费不允许操作")
	}
	//整个单据退掉
	old_logs := new(models.SaCollectfeesDoctororder)
	old_logs.CreatedAt = time.Now().Unix()
	old_logs.Id = 0
	old_logs.Archives = logs.Archives
	old_logs.DepartmentId = logs.DepartmentId
	old_logs.ParentId = logs_id
	old_logs.Number = s.create_number(logs.DepartmentId)
	old_logs.CreatedBy = value.CreatedBy
	old_logs.SumPayable = 0 - logs.SumPayable
	old_logs.TotalMoney = 0 - logs.TotalMoney
	old_logs.CashMoney = 0 - logs.CashMoney
	old_logs.CardMoney = 0 - logs.CardMoney
	old_logs.AlipayMoney = 0 - logs.AlipayMoney
	old_logs.WechatMoney = 0 - logs.WechatMoney

	if _, err := to.Insert(old_logs); err != nil {
		to.Rollback()
		return err
	}
	//生成明细
	if len(logs.SaCollectfeesDoctororderMiddle) == 0 {
		to.Rollback()
		return errors.New("单据明细不正确")
	}
	for _, val := range logs.SaCollectfeesDoctororderMiddle {
		//将未选择医嘱恢复为待结状态
		if strings.Index(","+value.DetailIds+",", fmt.Sprintf(",%d,", val.Id)) == -1 {
			val.Doctororder.PayStatus = 0
			if _, err := to.Update(val.Doctororder, "PayStatus"); err != nil {
				to.Rollback()
				return errors.New("医嘱更新失败" + err.Error())
			}
		}
		val.Id = 0
		val.SumPayable = 0 - val.SumPayable
		val.CreatedBy = value.CreatedBy
		val.CreatedAt = time.Now().Unix()
		val.TotalMoney = 0 - val.TotalMoney
		val.Collectfees = old_logs
		if _, err := to.Insert(val); err != nil {
			to.Rollback()
			return errors.New("单据明细写入失败" + err.Error())
		}
	}
	//原单据改为已退费状态
	logs.Status = 1
	if _, err := to.Update(logs, "status"); err != nil {
		to.Rollback()
		return errors.New("原单据更新失败" + err.Error())
	}
	to.Commit()
	return nil
}

//药房发药
func (s *CollectfeesService) SendDispensing(user models.BackendUser, archives_id int64, detail_id string) error {

	if archives_id == 0 {
		return errors.New("档案信息不存在")
	}
	if len(detail_id) <= 0 {
		return errors.New("没有可发药信息")
	}
	ids := strings.Split(detail_id, ",")
	if len(ids) == 0 {
		return errors.New("没有可发药信息")
	}
	to, _ := orm.NewOrm().Begin()
	for _, id := range ids {
		do := new(models.DoDoctorOrder)
		to.QueryTable(models.DoDoctorOrderTableName()).Filter("id", id).One(do)
		if do.Status != 1 || do.PayStatus != 1 || do.DrugSend != 0 {
			to.Rollback()
			return errors.New("所发药品状态不正常")
		}
		log := new(models.SaCollectfeesDispensing)
		log.Archives = do.Archives
		log.DepartmentId = do.DepartmentId
		log.CreatedBy = user.RealName
		log.CreatedAt = time.Now().Unix()
		log.Doctororder = do
		if _, err := to.Insert(log); err != nil {
			to.Rollback()
			return err
		}
	}

	if _, err := to.QueryTable(models.DoDoctorOrderTableName()).Filter("id__in", ids).Update(orm.Params{"drug_send": 1}); err != nil {
		to.Rollback()
		return err
	}
	to.Commit()
	return nil;
}
